package com.gking.aiService.utils.commonUtil;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import lombok.extern.slf4j.Slf4j;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JwtUtil {

    //有效期为
    private static final Long TOKEN_TIME_OUT = 24 * 60 * 60 * 1000L;// 60 * 60 * 1000L  一个小时
    //设置秘钥明文
    private static final String JWT_KEY = "GKing is No1 ^_^ !";
    // 最小刷新间隔(S)
    private static final int REFRESH_TIME = 300;


    //使用md5进行加密
    private static String MD5Encryption(String item) {
        try {
            // 创建MessageDigest对象并指定使用MD5算法
            MessageDigest md = MessageDigest.getInstance("MD5");

            // 将输入字符串转换为字节数组
            byte[] inputBytes = item.getBytes();

            // 使用MessageDigest更新字节数组
            md.update(inputBytes);

            // 执行哈希计算并获取结果
            byte[] hashedBytes = md.digest();

            // 将字节数组转换为十六进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : hashedBytes) {
                sb.append(String.format("%02x", b));
            }

            //   log.warn("加密后的密钥为： {}", sb.toString());
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "加密错误";
        }
    }

    /**
     * 生成签名，24h过期
     *
     * @param userId 用户id
     * @return token
     */
    public static String createToken(String userId) {
        try {
            // 设置过期时间
            Date date = new Date(System.currentTimeMillis() + TOKEN_TIME_OUT);
            // 私钥和加密算法
            Algorithm algorithm = Algorithm.HMAC256(MD5Encryption(JWT_KEY));
            // 设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("Type", "Jwt");
            header.put("alg", "HS256");
            // 返回token字符串
            return JWT.create()
                    .withHeader(header)
                    .withClaim("userId", userId)
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 生成token，自定义过期时间 毫秒
     *
     * @param userId     用户id
     * @param expireDate 自定义时间
     * @return token
     */
    public static String createToken(String userId, long expireDate) {
        try {
            // 设置过期时间
            Date date = new Date(System.currentTimeMillis() + expireDate);
            // 私钥和加密算法
            Algorithm algorithm = Algorithm.HMAC256(MD5Encryption(JWT_KEY));
            // 设置头部信息
            Map<String, Object> header = new HashMap<>(2);
            header.put("Type", "Jwt");
            header.put("alg", "HS256");
            // 返回token字符串
            return JWT.create()
                    .withHeader(header)
                    .withClaim("userId", userId)
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 检验token是否正确
     *
     * @param token token
     * @return 提取出来的明文信息 用户凭证，校验错误返回 null
     */
    public static String verifyToken(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(MD5Encryption(JWT_KEY));
//            log.error("algorithm:{}", MD5Encryption(JWT_KEY));
//            log.error("algorithm:{}", algorithm);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getClaim("userId").asString() ;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 查看token剩余多少时间
     *
     * @param token token
     * @return 剩余时间
     */
    public static long checkTime(String token) {
        Algorithm algorithm = Algorithm.HMAC256(MD5Encryption(JWT_KEY));
        JWTVerifier verifier = JWT.require(algorithm).build();
        DecodedJWT jwt = verifier.verify(token);
        Date expiresAt = jwt.getExpiresAt();
        Date now = new Date();
        return expiresAt.getTime() - now.getTime();
    }
}